﻿// 902 欧拉路判断.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <memory.h>


using namespace std;
/*
http://oj.daimayuan.top/course/14/problem/763

给你一张无向图，你需要判断这张图中是否存在欧拉路。

图用以下形式给出：

第一行输入两个整数 n,m
，表示图的顶点数和边数，顶点编号从 1
 到 n
。

接下来 m
 行，每行两个整数 x,y
，表示 x
 和 y
 之间有一条边。

输出一个字符串 Yes 或者 No，表示是否存在欧拉路， Yes 表示存在。

输入格式
第一行两个整数 n,m
。

接下来 m
 行，每行有两个整数，代表一条边。

输出格式
输出一个字符串表示答案。

样例输入
2 2
1 1
1 2
样例输出
Yes
数据规模
对于所有数据，保证 2≤n≤100000,0≤m≤100000,1≤x,y≤n
*/

struct Node {
	int y, idx;
	Node(int _y, int _idx) { y = _y; idx = _idx; }
};
vector<Node>  edge[100010];
int n, m, cnt = 1, l, f[100010], v[100010], c[100010], d[100010];
bool b[200010];

void dfs(int x) {
	while (f[x] < v[x]) {
		int y = edge[x][f[x]].y, idx = edge[x][f[x]].idx;
		if (!b[idx]) {
			++f[x];
			b[idx] = b[idx ^ 1] = true;
			dfs(y);
			c[++l] = y;
		}
		else {
			++f[x];
		}
	}
}

void Euler() {
	int x = 0, y = 0;
	for (int i = 1; i <= n; i++) {
		if (d[i] & 1)
			++y, x = i;
	}

	if (y && y != 2) {
		printf("No\n");
		return;
	}
	if (!x) {
		for (int i = 1; i <= n; i++)
			if (d[i])
				x = i;
	}

	memset(b, false, sizeof b);
	memset(f, 0, sizeof f);
	l = 0;
	dfs(x);
	c[++l] = x;

	if (l != m + 1) {
		printf("No\n");
		return;
	}

	printf("Yes\n");
	/*for (int i = l; i; --i) {
		//printf("%d",c[i]);
	}
	*/
}



int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= m; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		edge[x].push_back(Node(y, ++cnt));
		edge[y].push_back(Node(x, ++cnt));
		++d[x]; ++d[y];
	}
	for (int i = 1; i <= n; i++) {
		v[i] = edge[i].size();
	}
	Euler();

	return 0;
}


 	